﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using DAL.Infrastructure;
using DAL.Interfaces;
using BAL.Infrastructure;
using BAL.Interfaces;
using System.Data;
using System.Data.Entity;
using System.Web;
using BibliotecaVirtual.Models;
using BibliotecaVirtual.Libreria;
using DAL.Models;

namespace BAL
{
    public class BALReservaciones : ServiceBase<Reservaciones>, IReservacionesService
    {
        private IEjemplarsService BALEjemplar = null;
        private IPrestamosService BALPrestamo = null;
        private IMaterialsService BALMaterial = null;

        public BALReservaciones(IRepository<Reservaciones> repository, IApplicationContext context,
                        IEjemplarsService EjemplarsService,
                        IPrestamosService PrestamosService,
                        IMaterialsService MaterialsService) 
            : base(repository, context)
        {
            BALEjemplar = EjemplarsService;
            BALPrestamo = PrestamosService;
            BALMaterial = MaterialsService;
        }

        public override IQueryable<Reservaciones> GetAllValidados()
        {
            try
            {
                return _repository.GetAllValidados().Include(m => m.EstadoReservas).Include(m => m.Materials).Include(m => m.Socios);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IQueryable<Reservaciones> GetBySocioID(long id)
        {
            try
            {
                return _repository.GetAllValidados().Include(m => m.EstadoReservas).Include(m => m.Materials).Include(m => m.Socios).Where(m => m.SocioId == id);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public bool PuedoReservar(Reservaciones reservaciones)
        {
            try
            {
                 IEnumerable<Reservaciones> reservas = from q in context.Reservaciones
                                                      where q.SocioId == reservaciones.SocioId && 
                                                            q.EstadoReservaId==1 select q;
                 return (reservas.Count<Reservaciones>() >= 5);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Reservaciones GetValidadoById(long id)
        {
            try
            {
                return (context.Reservaciones.Include(r => r.Socios).Include(r => r.Materials).Include(r => r.EstadoReservas).First(x => x.id == id));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Reservaciones Cancelar(Reservaciones reservacion)
        {
            try
            {
                reservacion.EstadoReservas = (from p in context.EstadosReservas
                                      where p.Descripcion == Constantes.EstadoReservas.CANCELADA
                                      select p).First<EstadoReservas>();

                reservacion.EstadoReservaId = reservacion.EstadoReservas.id;
                return reservacion;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void ModificarEstadoReserva(ref Reservaciones reservaciones)
        {
            try
            {
                Materials material = BALMaterial.GetByID(reservaciones.MaterialId);

                if (material.CantidadEjemplaresDisponibles > 0)
                {
                    reservaciones.EstadoReservaId = Constantes.EstadoReservas.ESTADO_ACTIVA;
                }
                else
                {
                    reservaciones.EstadoReservaId = Constantes.EstadoReservas.ESTADO_EN_ESPERA;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<Ejemplars> GetEjemplaresDisponibles(Reservaciones reservacion)
        {
            try{
                 reservacion.Materials.Ejemplars = context.Ejemplares.Include(e => e.EstadoEjemplars).Where(e => e.MaterialId == reservacion.Materials.id).ToList();

                IEnumerable<Ejemplars> disponibles = from d in reservacion.Materials.Ejemplars
                                                    where d.EstadoEjemplars.Descripcion == Constantes.EstadoEjemplares.DISPONIBLE 
                                                    select d;
                return disponibles;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<Reservaciones> GetReservasDisponibles(Reservaciones reservacion)
        {
            try{
                IEnumerable<Reservaciones> reservas = from r in reservacion.Materials.Reservaciones
                                                      where r.FechaEfectivo < reservacion.FechaEfectivo
                                                      select r;
                return reservas;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void GuardarDespacho(Reservaciones reservacion,IEnumerable<Ejemplars> ejemplares_disponibles)
        {
            try{
                reservacion.EstadoReservas = (from p in context.EstadosReservas
                                              where p.Descripcion == Constantes.EstadoReservas.FINALIZADA 
                                              select p).First<EstadoReservas>();
                long id_ejemplar = ejemplares_disponibles.First().id;

                Ejemplars ejemplar = context.Ejemplares.First<Ejemplars>(r => r.id == id_ejemplar);

                ejemplar.EstadoEjemplarId = (from d in context.EstadosEjemplares
                                             where d.Descripcion == Constantes.EstadoEjemplares.NO_DISPONIBLE 
                                             select d).First().id;

                reservacion.EstadoReservaId = reservacion.EstadoReservas.id;

                Prestamos prestamo = new Prestamos();

                prestamo.EjemplarId = reservacion.Materials.Ejemplars.First<Ejemplars>().EstadoEjemplarId;

                prestamo.EstadoPrestamoId = (from p in context.EstadosPrestamos
                                        where p.Descripcion == Constantes.EstadoPrestamos.ACTIVO 
                                        select p).First<EstadoPrestamoes>().id;

                prestamo.FechaEstimadaDevolucion = DateTime.Now.AddDays(30);
                prestamo.FechaEfectivaDevolucion = DateTime.Now.AddDays(-1.0);
                prestamo.FechaPrestamo = DateTime.Now;
                prestamo.id = reservacion.Socios.Prestamos.Count() + 1;
                prestamo.SocioId = reservacion.SocioId;

                //Create(reservacion);
                BALPrestamo.Create(prestamo); 
                BALEjemplar.Edit(ejemplar);
                Edit(reservacion);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

    }
}
